package net.qiqb.core.domain.event;

import lombok.Getter;
import net.qiqb.core.domain.annotation.Entity;
import net.qiqb.core.domain.annotation.EntityId;
import net.qiqb.core.domain.event.types.DomainEventStatus;
import net.qiqb.core.executing.EntityIdGeneratorHolder;
import net.qiqb.core.trace.TraceId;

import java.time.LocalDateTime;

@Entity
public class DomainEvent implements java.io.Serializable {

    /**
     * 事件id
     */
    @EntityId
    @Getter
    private final String id;

    private String source;

    private final String name;

    /**
     * 可以通过此值来进行追踪事件的。
     */
    @Getter
    private TraceId traceId;

    /**
     * 产生事件的时间
     */
    @Getter
    private final LocalDateTime timestamp = LocalDateTime.now();

    @Getter
    private final String creator;

    @Getter
    private DomainEventStatus status;

    @Getter
    private final Object payload;

    /**
     * @param source  事件源，命令
     * @param creator 创建事件的对象
     * @param payload 领域事件携带的信息
     */
    public DomainEvent(String source, String creator, Object payload) {
        // 默认采用雪花id
        this.id = EntityIdGeneratorHolder.get(Long.class).generate().toString();
        // 默认按照名称来找
        this.source = source;
        this.name = payload.getClass().getName();
        this.creator = creator;
        this.status = DomainEventStatus.ready;
        this.payload = payload;
    }

    public DomainEvent(String id, String source, String creator, Object payload) {
        this.source = source;
        // 默认采用雪花id
        this.id = id;
        this.name = payload.getClass().getName();
        this.creator = creator;
        this.status = DomainEventStatus.ready;
        this.payload = payload;
    }

    public static DomainEvent load(String id, String source, String creator, Object payload) {
        return new DomainEvent(id, source, creator, payload);

    }


    public void sending() {
        this.status = DomainEventStatus.sending;
    }

    public void sent() {
        this.status = DomainEventStatus.sent;
    }


    public String getSource() {
        return source;
    }
}